package com.tfjybj.itoo.teach.provider.service.impl;

import org.apache.dubbo.config.annotation.Reference;;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.dmsdbj.itoo.authorizationManagement.entity.OrganizationEntity;
import com.dmsdbj.itoo.authorizationManagement.facade.OrganizationFacade;
import com.dmsdbj.itoo.tool.base.service.impl.BaseServicePlusImpl;
import com.dmsdbj.itoo.tool.business.ItooResult;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tfjybj.itoo.teach.entity.AcademyEntity;
import com.tfjybj.itoo.teach.model.AcademyModel;
import com.tfjybj.itoo.teach.provider.dao.AcademyDao;
import com.tfjybj.itoo.teach.provider.service.AcademyService;
import com.tfjybj.itoo.teach.template.AcademyExportTemplate;
import com.tfjybj.itoo.teach.template.AcademyTemplate;
import lombok.extern.slf4j.Slf4j;
import org.jplus.hyberbin.excel.utils.ExcelUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.*;

import static com.tfjybj.itoo.teach.provider.until.DemoConstants.*;

/**
 * AcademyService接口实现类
 * ${base}表
 *
 * @author 田成荣
 * @version 2.0.0
 * @since 2.0.0 2018-11-08 19:34:10
 */
@Service("academyService")
@Slf4j
public class AcademyServiceImpl extends BaseServicePlusImpl<AcademyDao, AcademyEntity> implements AcademyService {

    @Resource
    private RedisTemplate<String, AcademyTemplate> redisTemplate;

    //@Autowired(required = false)
    //private OrganizationFacade organizationFacade;

	//region 模板生成
    @Resource
    private AcademyDao academyDao;

    @Override
    public PageInfo<AcademyEntity> queryByLikeName(String name, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return new PageInfo<>(academyDao.queryLikeName(name));
    }
	//endregion

    /* **********************************以下为非模板生成的内容********************************* */
    /**
     *根据学院或者机构id查询学院或者机构名称
     * @param ids 学院或者机构id
     * @return 查询的学院或者机构名称
     * @author 杨燕梅
     * @since 2.0.0 2018-11-17 15:55:17
     */
    @Override
    public List<AcademyModel> queryInfoByAcadIdOrInstId(List<String> ids){
        return academyDao.queryInfoByAcadIdOrInstId(ids);
    }

    /**
     *查询所有学院或者机构名称
     * @return 所有的学院或者机构名称
     * @author 杨燕梅
     * @since 2.0.0 2018-11-17 21:29:12
     */
    @Override
    public List<AcademyModel>queryAcadOrInstInfo(){
        return academyDao.queryAcadOrInstInfo();
    }

    /**
     * 查询所有Academy
     * @author 杨燕梅
     * @since 2.0.0 2018-11-23 11:52:12
     */
    @Override
    public List<AcademyModel>queryAllAcademy(){
        return academyDao.queryAllAcademy();
    }

    /**
     * 查询所有教学部门（带分页）
     * @author 杨燕梅
     * @since 2.0.0 2018-12-19 15:17:30
     */
    @Override
    public PageInfo<AcademyModel> queryAllAcademyPageInfo(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return new PageInfo<>(academyDao.queryAllAcademyPageInfo());
    }

    /**
     * 根据教学部门名称或教学部门简称模糊查询academy(带分页)
     * @param searchContent  教学部门名称
     * @param pageNum   页码
     * @param pageSize 页数
     * @return 模糊查询的academy
     * @author 杨燕梅
     * @since 2.0.0 2018-12-6 21:24:36
     */
    @Override
    public PageInfo<AcademyModel> queryByLikeNameOrAbbreviation(String searchContent, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return new PageInfo<>(academyDao.queryByLikeNameOrAbbreviation(searchContent.trim()));
    }

    /**
     * 根据教学部门ID查询教学部门详情
     *
     * @param idList 教学部门ID
     * @return 教学部门实体集合
     * @author 杨燕梅
     * @since 2.0.0 2018-12-11 10:14:26
     */
    @Override
    public List<AcademyModel> queryAcademyById(List<String> idList) {
        return academyDao.queryAcademyById(idList);
    }

    /**
     * 根据ID导出教学部门信息
     *
     * @param response 响应
     * @param idList   教学部门ID
     * @return 导出结果信息
     * @author 杨燕梅
     * @since 2.0.0 2018-12-11 09:45:16
     */
    @Override
    public ItooResult exportByAcademyId(HttpServletResponse response, List<String> idList) {
        Map<Serializable, Serializable> map = new HashMap<>(16);

        map.put(SHEET_NAME, "教学部门");
        //要导出的字段
        map.put(COLUMNS, new String[]{"code", "name", "abbreviation", "remark"});
        //导出表格的标题
        map.put(TITLE, "教学部门信息");
        map.put(NAME, "导出的教学部门");
        //要导出的数据
        List<AcademyExportTemplate> academyExportTemplateList = new ArrayList<>();

        List<AcademyModel> academyModelList = academyDao.queryAcademyById(idList);
        for (AcademyModel academyModel : academyModelList) {
            AcademyExportTemplate academyExportTemplate = new AcademyExportTemplate();
            BeanUtils.copyProperties(academyModel, academyExportTemplate);
            academyExportTemplateList.add(academyExportTemplate);
        }
        //为空不进行导出
        if (CollectionUtils.isEmpty(academyExportTemplateList)) {
            return ItooResult.build(ItooResult.FAIL, "没有要导出的数据！");
        }
        map.put(DATA_LIST, (Serializable) academyExportTemplateList);

        //导出
        try {
            ExcelUtil.exportExcel(map, response);
        } catch (Exception e) {
            log.error("导出失败,未知的异常--" + e);
            return ItooResult.build(ItooResult.FAIL, "导出信息失败！", e);
        }
        return ItooResult.build(ItooResult.SUCCESS, "导出信息成功！");
    }

    /**
     * 根据条件导出教学部门
     *
     * @param response     响应
     * @return 导出结果信息
     * @author 杨燕梅
     * @since 2.0.0 2018-12-13 08:11:09
     */
    @Override
    public ItooResult exportByStrLike(HttpServletResponse response, String searchContent) {
        Map<Serializable, Serializable> map = new HashMap<>(16);

        map.put(SHEET_NAME, "教学部门");
        //要导出的字段
        map.put(COLUMNS,  new String[]{"code", "name", "abbreviation", "remark"});
        //导出表格的标题
        map.put(TITLE, "教学部门信息");
        map.put(NAME, "按条件导出的教学部门信息");
        //要导出的数据
        List<AcademyExportTemplate> academyExportTemplateList = new ArrayList<>();
        List<AcademyModel> academyModelList = academyDao.queryByLikeNameOrAbbreviation(searchContent);
        for (AcademyModel academyModel : academyModelList) {
            AcademyExportTemplate academyExportTemplate = new AcademyExportTemplate();
            BeanUtils.copyProperties(academyModel, academyExportTemplate);
            academyExportTemplateList.add(academyExportTemplate);
        }
        //为空不进行导出
        if (CollectionUtils.isEmpty(academyExportTemplateList)) {
            return ItooResult.build(ItooResult.FAIL, "没有要导出的数据！");
        }
        map.put(DATA_LIST, (Serializable) academyExportTemplateList);

        //导出
        try {
            ExcelUtil.exportExcel(map, response);
        } catch (Exception e) {
            log.error("导出失败,未知的异常--" + e);
            return ItooResult.build(ItooResult.FAIL, "导出信息失败！", e);
        }
        return ItooResult.build(ItooResult.SUCCESS, "导出信息成功！");
    }

    /**
     * 下载教学部门模板，批量导入使用
     *
     * @param response 响应
     * @return 下载模板是否成功
     * @author 杨燕梅
     * @since 2.0.0 2018-11-15 08:53:53
     */
    @Override
    public boolean downLoadTemplate(HttpServletResponse response) {
        Map<Serializable, Serializable> map = new HashMap<>(16);
        List<AcademyTemplate> templateList = new ArrayList<>();
        AcademyTemplate academyTemplate = new AcademyTemplate();
        academyTemplate.setCode("05");
        academyTemplate.setName("物理与电子信息学院");
        academyTemplate.setAbbreviation("物电");
        academyTemplate.setRemark("导入数据模板");
        templateList.add(academyTemplate);
        //sheet的名字
        map.put(SHEET_NAME, "教学部门信息");
        //需要导入的字段
        map.put(COLUMNS,   new String[]{"code", "name", "abbreviation", "remark"});
        //表格的标题
        map.put(TITLE, "教学部门信息");
        map.put(NAME, "教学部门信息模板");
        map.put(DATA_LIST, (Serializable) templateList);
        try {
            ExcelUtil.exportExcel(map, response);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 批量导入教学部门信息
     * @param multipartFile
     * @param request
     * @param response
     * @return
     * @author 杨燕梅
     * @since 2.0.0 2018-12-5 11:09:40
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ItooResult importTemplate(MultipartFile multipartFile, HttpServletRequest request, HttpServletResponse response) {
        response.setContentType("UTF-8");
        try {
            //校验文件是否存在
            String fileName = multipartFile.getOriginalFilename();
            if (fileName == null) {
                log.error("导入失败,fileName is null!");
                return ItooResult.build(ItooResult.FAIL, "传入的文件为空！");
            }
            //EXCEL解析成List
            Map<Serializable, Serializable> map = new HashMap<>(4);
            map.put(SHEET_NAME, "教学部门");
            map.put(CLASS, AcademyTemplate.class);
            List<AcademyTemplate> academyTemplateList = ExcelUtil.importExcel(Objects.requireNonNull(fileName), map, request, response);
            if (CollectionUtils.isEmpty(academyTemplateList)) {
                return ItooResult.build(ItooResult.FAIL, "导入的数据为空，请填写！");
            }
            //定义导入的错误数据集合并存redis中形式的<String,AcademyTemplate>
            List<AcademyTemplate> errorATList = new ArrayList<>();
            String errorATListId = IdWorker.getIdStr();
            Long size = redisTemplate.opsForZSet().size(errorATListId);
            size = size == null ? 0L : size;
            //循环处理数据
            for (AcademyTemplate excelAT : academyTemplateList) {
                if (!this.verify(excelAT)) {
                    AcademyTemplate academyTemplate = new AcademyTemplate();
                    BeanUtils.copyProperties(excelAT, academyTemplate);
                    errorATList.add(academyTemplate);
                    redisTemplate.opsForZSet().add(errorATListId, academyTemplate, size + 1);
                    continue;
                }
                AcademyEntity academyEntity = new AcademyEntity();
                //将导入内容放到entity中对应的属性中去
                BeanUtils.copyProperties(excelAT,academyEntity);
                //教学部门编码
                academyEntity.setCode(excelAT.getCode());
                //教学部门名称
                academyEntity.setName(excelAT.getName());
                //教学部门简称
                academyEntity.setAbbreviation(excelAT.getAbbreviation());
                //备注
                academyEntity.setRemark(excelAT.getRemark());
                //类型
                academyEntity.setType(1);
                this.save(academyEntity);
                this.saveToAuth(academyEntity);
            }
            //不符合条件的信息返回
            if (!CollectionUtils.isEmpty(errorATList)) {
                return ItooResult.build("0001", "部分导入失败", errorATListId);
            }
        } catch (Exception e) {
            return ItooResult.build(ItooResult.FAIL, "导入数据异常！", e);
        }
        return ItooResult.build(ItooResult.SUCCESS, "导入数据成功！");
    }

    /**
     * 判断批量导入的信息是否符合要求
     *
     * @param academyTemplate 需要导入的信息
     * @return boolean 导入的字段是否为空
     * @author 杨燕梅
     * @since 2.0.0 2018-11-30 08:52:33
     */
    private boolean verify( AcademyTemplate academyTemplate) {
        //判断教学部门代码是否填写
        if (StringUtils.isEmpty(academyTemplate.getCode())) {
            academyTemplate.setFailReason("教学部门代码未填写");
            log.warn("导入失败,教学部门代码未填写,excelAcademyEntity-{}", academyTemplate);
            return false;
        }
        //判断教学部门名称是否填写
        if (StringUtils.isEmpty(academyTemplate.getName())) {
            academyTemplate.setFailReason("教学部门名称未填写");
            log.warn("导入失败,教学部门名称未填写,excelAcademyEntity-{}", academyTemplate);
            return false;
        }
        //判断教学部门是否重复
        if (!CollectionUtils.isEmpty(academyDao.queryByCodeAndNameExist(academyTemplate.getCode(),academyTemplate.getName()))){
            academyTemplate.setFailReason("教学部门已存在");
            log.warn("导入失败,教学部门已存在,excelAcademyEntity-{}", academyTemplate);
            return false;
        }
        return true;
    }

    /**
     * 根据errorListId导出未成功导入的信息
     *
     * @param response    响应
     * @param errorListId 为成功导入的分组id
     * @return 导出结果
     * @author 杨燕梅
     * @since 1.0.0 2018-12-1 19:39:17
     */
    @Override
    public boolean exportErrorList(String errorListId, HttpServletResponse response){
        //redis取出没有成功导入的教学部门信息
        Set set = redisTemplate.opsForZSet().range(errorListId, 0, -1);
        List<AcademyExportTemplate> academyExportTemplates=new ArrayList<>(set);
        //清空redis数据
        redisTemplate.delete(errorListId);
        //导出没有成功导入的教学部门信息
        if(academyExportTemplates.size()==0){
            return false;
        }
        Map<Serializable, Serializable> errorMap = new HashMap<>(16);
        errorMap.put(NAME, "未导入的教学部门信息");
        errorMap.put(SHEET_NAME, "教学部门信息");
        errorMap.put(TITLE, "未导入的教学部门信息");
        errorMap.put(COLUMNS, new String[]{"code", "name", "abbreviation", "remark", "failReason"});
        errorMap.put(DATA_LIST, (Serializable) academyExportTemplates);
        try {
            ExcelUtil.exportExcel(errorMap, response);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * 根据教学部门Id查询教学部门名称
     * @param name  教学部门简称
     * @return 模糊查询的academy
     * @author 杨燕梅
     * @since 2.0.0 2018-12-2 18:55:11
     */
    @Override
    public String queryAcademyIdByName(String name) {
       return academyDao.queryAcademyIdByName(name);
    }

    /**
     * 根据教学部门代码和教学部门名称查询教学部门是否已存在
     *
     * @param code   教学部门代码
     * @param name   教学部门名称
     * @return 教学部门信息
     * @author 杨燕梅
     * @since 2.0.0 2018-11-29 19:37:30
     */
    @Override
    public List<AcademyEntity>queryByCodeAndNameExist(String code, String name){
        return academyDao.queryByCodeAndNameExist(code,name);
    }

    /**
     * 将数据保存到权限中去
     *
     * @param academyEntity
     * @author 李建帅
     * @since 2.0.0 2018-12-9 19:18:10
     */
    @Override
    public void saveToAuth(AcademyEntity academyEntity){
//        List<OrganizationEntity> organizationEntityList = new ArrayList<>();
//        OrganizationEntity organizationEntity = new OrganizationEntity();
//        organizationEntity.setId(academyEntity.getId());
//        organizationEntity.setOrganizationName(academyEntity.getName());
//        organizationEntity.setPId("87LkGQNeDpE7H6paYhZ7zZ");
//        organizationEntity.setCompanyId("lfsfxy111222");
//        organizationEntityList.add(organizationEntity);
//
//        try {
//            organizationFacade.synchroOrganization(organizationEntityList);
//        } catch (Exception e) {
//            log.error("将组织机构信息同步到权限中心失败！", e);
//        }
    }

    /**
     * 无参查询Academy表所有学院信息
     *
     * @author 智雪艳
     * @since 2.0.0 2019-05-23 14:13:09
     */
    @Override
    public List<AcademyEntity> findAcademy() {
        return academyDao.findAcademy();
    }

    /**
     * 无参查询所有二级学院,去除没有专业的学院,附加专业数
     *
     * @return 二级学院集合
     * @author 智雪艳
     * @since 2.0.0 2019-05-23 14:13:09
     */
    @Override
    public List<AcademyModel> selAcademy() {
        return academyDao.selAcademy();
    }
}
